package cc.vv.baselibrary.util.voice;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;

import java.io.IOException;

import cc.vv.baselibrary.vFinal.BTFileName;
import cc.vv.baselibrary.vFinal.BTSPKey;
import cc.vv.lkbasecomponent.base.app.LKBaseApplication;
import cc.vv.lkbasecomponent.util.LKSPUtil;

/**
 * 语音播放操作
 *
 * @author: NPF
 * @date: 2018/3/30.
 */
public class IMVoicePlayer implements MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {
    private MediaPlayer mMediaPlayer;
    private MediaPlayer playerOther;
    private AudioManager mAudioManager;
    private PlayerInter mPlayerInter;
    private static IMVoicePlayer mInstance;


    private IMVoicePlayer() {
    }

    public static IMVoicePlayer getInstance() {
        if (null == mInstance) {
            synchronized (IMVoicePlayer.class) {
                if (null == mInstance) {
                    mInstance = new IMVoicePlayer();
                }
            }
        }
        return mInstance;
    }

    /**
     * 初始化播放控件
     */
    private void initPlayer(boolean isCoerceAmplify) {
        try {
            stop();
            mMediaPlayer = new MediaPlayer();
            mAudioManager = (AudioManager) LKBaseApplication.getApplication().getSystemService(Context.AUDIO_SERVICE);
            if (!isCoerceAmplify) {
                isCoerceAmplify = LKSPUtil.getInstance(BTFileName.SP_NAME).getBoolean(BTSPKey.KEY_VOICEPLAY_ISOUTSIDE);
            }
            BTVoicePlayerUtil.getInstance().setSpeakerPhoneOn(mMediaPlayer, mAudioManager, isCoerceAmplify);
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnErrorListener(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 标记上一次播放地址
     */
    private String mUrl;

    /**
     * 播放语音
     *
     * @param url             播放地址
     * @param isCoerceAmplify 是否强制外方
     * @param playerInter     播放状态回调
     */
    @NonNull
    public void playUrl(@NonNull String url, boolean isCoerceAmplify, @NonNull PlayerInter playerInter) {
        if (!TextUtils.isEmpty(url)) {
            if (url.equals(mUrl)) {
                stop();
            } else {
                if (null != mPlayerInter) {
                    mPlayerInter.onStop();
                }
                if (mMediaPlayer == null) {
                    initPlayer(isCoerceAmplify);
                }
                this.mUrl = url;
                this.mPlayerInter = playerInter;
                try {
                    mMediaPlayer.reset();
                    mMediaPlayer.setDataSource(url);
//                    mMediaPlayer.prepare();
                    mMediaPlayer.prepareAsync();
                    mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            playerOther = mp;
                            mp.start();
                            if (null != mPlayerInter) {
                                mPlayerInter.onStart();
                            }
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                    stop();
                }
            }
        }
    }

    /**
     * 播放语音
     *
     * @param url
     */
    @NonNull
    public void playUrlOther(@NonNull String url, @NonNull PlayerInter playerInter, boolean isTingTong) {
        try {
            stop();
            mMediaPlayer = new MediaPlayer();
            mAudioManager = (AudioManager) LKBaseApplication.getApplication().getSystemService(Context.AUDIO_SERVICE);
            if (isTingTong) {
                BTVoicePlayerUtil.getInstance().setSpeakerPhoneOn(mMediaPlayer, mAudioManager, true);
            } else {
                BTVoicePlayerUtil.getInstance().setSpeakerPhoneOn(mMediaPlayer, mAudioManager, false);
            }
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnErrorListener(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (null != mPlayerInter) {
            mPlayerInter.onStop();
        }
        if (!TextUtils.isEmpty(url)) {
            this.mUrl = url;
            this.mPlayerInter = playerInter;
            if (mMediaPlayer == null) {
                initPlayer(false);
            }
            try {
                mMediaPlayer.reset();
                mMediaPlayer.setDataSource(url);
//                mMediaPlayer.prepare();
                mMediaPlayer.prepareAsync();
                mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mp.start();
                        if (null != mPlayerInter) {
                            mPlayerInter.onStart();
                        }
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 暂停
     */
    public void pause() {
        if (mMediaPlayer != null) {
            mMediaPlayer.pause();
        }
    }

    /**
     * 播放
     */
    public void play() {
        if (mMediaPlayer != null) {
            mMediaPlayer.start();
        }
    }


    public int currentPosition() {
        if (playerOther != null && playerOther.isPlaying()) {
            return playerOther.getCurrentPosition();
        }
        return -1;
    }


    public int totalDuration() {
        if (playerOther != null && playerOther.isPlaying()) {
            return playerOther.getDuration();
        }
        return -1;
    }

    private void test() {
        if (mMediaPlayer != null) {
            mMediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
                @Override
                public void onBufferingUpdate(MediaPlayer mp, int percent) {
                }
            });
        }
    }

    /**
     * 停止
     */
    public void stop() {
        mUrl = "";
        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
            playerOther = null;
            if (null != mPlayerInter) {
                mPlayerInter.onStop();
            }
        }
        if (null != mAudioManager) {
            mAudioManager.setMode(AudioManager.MODE_NORMAL);
            mAudioManager = null;
        }
    }

    /**
     * 准备并播放
     *
     * @param mediaPlayer
     */
    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        mediaPlayer.start();
        if (null != mPlayerInter) {
            mPlayerInter.onStart();
        }
    }

    /**
     * 播放完成回调
     *
     * @param mediaPlayer
     */
    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        mUrl = "";
        if (null != mMediaPlayer && null != mAudioManager) {
            mMediaPlayer.release();
            mAudioManager.setMode(AudioManager.MODE_NORMAL);
            mMediaPlayer = null;
            playerOther = null;
            mAudioManager = null;
            if (null != mPlayerInter) {
                mPlayerInter.onCompletion();
            }
        }
    }

    /**
     * 播放出现错误
     *
     * @param mediaPlayer
     * @param what
     * @param extra
     * @return
     */
    @Override
    public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
        onCompletion(mediaPlayer);
        stop();
        if (null != mPlayerInter) {
            mPlayerInter.onError();
        }
        return false;
    }

    /**
     * 语音播放状态回调
     */
    public interface PlayerInter {
        void onStart();

        void onCompletion();

        void onError();

        void onStop();
    }
}
